#include "tnotify.h"
#include "QtGui"
#include "tnotifywindow.h"
#include "iostream"

TNotify::TNotify(QObject *parent) :
    QObject(parent),
    notifyNum(0),
    animation(new QSequentialAnimationGroup())
{
    QObject::connect(animation, SIGNAL(finished()), this, SLOT(clearAnimation()));
}

void TNotify::newNotify(QString Title, QString Text){
    int height = 0;
    for (int i=0; i < notifyList.count(); i++){
        height = height + notifyList.at(i)->height();
        std::cout << "Height: " << height << std::endl;
    }
    notifyList.append(new TNotifyWindow(Title, arrangeText(Text,250,6), height));
    QObject::connect(notifyList.last(), SIGNAL(requestDelete(TNotifyWindow*)), this, SLOT(deleteNotify(TNotifyWindow*)));
    std::cout << "Notification number: " << notifyList.count() << std::endl;
    notifyNum++;
}

void TNotify::deleteNotify(TNotifyWindow* notify){
    int notifyIndex = notifyList.indexOf(notify);
    int notifyHeight = notify->height();
    notify->animateHide();
    notifyList.removeOne(notify);

    for (int i = notifyIndex; i < notifyList.count(); i++){
        notifyList.at(i)->animateDown(notifyHeight);
    }
}

QString TNotify::arrangeText(QString Text, int MaximumWidth, int MaximumRows){
    QString newText;
    QString tmp;
    QString line;

    QLabel lbl;
    QFontMetrics* fm = new QFontMetrics(lbl.font());
    QRegExp newLineExp("^(.*)$");
    QRegExp wordExp("\\b(\\S+)\\b");

    tmp = Text;
    int linePos =0;
    int i =1;
    std::cout << "Start lining." << std::endl;
    while ((linePos = newLineExp.indexIn(tmp,linePos)) != -1 and i <= MaximumRows){
        std::cout << "Line found." << std::endl;
        line = newLineExp.cap(0);
        int pos =0;
        if (line == fm->elidedText(line, Qt::ElideRight, MaximumWidth)){
            std::cout << "Line is less then maximum line width. " << fm->width(line) << "<" << MaximumWidth << std::endl;
            newText.append(line);
        }else{
            std::cout << "Line too long. Lets wrap it. " << fm->width(line) << ">" << MaximumWidth << std::endl;
            while((pos = wordExp.indexIn(line,pos)) != -1 and i <= MaximumRows){
                std::cout << "Found a word \"" << wordExp.cap(1).toStdString() << "\"."  << std::endl;
                if (line.left(pos+wordExp.cap(0).size()) == fm->elidedText(line.left(pos+wordExp.cap(0).size()),Qt::ElideRight, MaximumWidth)){
                    //do nothing -> next loop cicle
                    std::cout << "Not enough width. Skipping to next word. " << pos+wordExp.cap(0).size() << "<" << MaximumWidth << std::endl;
                    pos++;
                }else if(pos != 0){
                    std::cout << "Time to wrap line. " << pos+wordExp.cap(0).size() << ">" << MaximumWidth << std::endl;
                    if (i < MaximumRows){
                        std::cout << "\"" << line.left(pos).size() << "\" added. " << pos << "<" << MaximumWidth << std::endl;
                        newText.append(line.left(pos)).append("\n");
                        line = line.mid(pos);
                        pos = 0;
                        i++;
                    }else if(i == MaximumRows){
                        std::cout << "debug 2.2" << std::endl;
                        newText.append(fm->elidedText(line.left(pos+wordExp.cap(0).size()),Qt::ElideRight, MaximumWidth));
                        i++;
                    }else{
                        std::cout << "debug 2.3" << std::endl;
                        std::cout << "An error has occured!" << std::endl;
                        return 0;
                    }
                }else if(pos == 0){
                    std::cout << "Word in this line is too long. " << wordExp.cap(0).size() << ">" << MaximumWidth << std::endl;
                    if (i < MaximumRows){
                        std::cout << "Let's wrap it" << std::endl;
                        int j = 0;
                        while(line.left(j) == fm->elidedText(line.left(j),Qt::ElideRight, MaximumWidth)){
                            std::cout << line.left(j).toStdString() << " "<< j << "<" << MaximumWidth << std::endl;
                            j++;
                        }
                        newText.append(line.left(j-1)).append("\n");
                        line = line.mid(j);
                        i++;
                    }else if(i == MaximumRows){
                        std::cout << "debug 3.2" << std::endl;
                        newText.append(fm->elidedText(line,Qt::ElideRight, MaximumWidth));
                        i++;
                    }else{
                        std::cout << "debug 3.3" << std::endl;
                        std::cout << "An error has occured!" << std::endl;
                        return 0;
                    }
                }else{
                    std::cout << "debug 4" << std::endl;
                    std::cout << "An error has occured!" << std::endl;
                    return 0;
                }
            }
        }

        i++;
        linePos++;
    }
    return newText;
}

void TNotify::clearAnimation(void){
    parallelGroup.clear();
    animation->clear();
}
